package com.cxs.musicplaywidget.player.player;

import com.cxs.musicplaywidget.player.IMusicPlayer;
import com.cxs.musicplaywidget.player.data.MusicData;
import com.cxs.musicplaywidget.player.data.MusicInfo;
import com.cxs.musicplaywidget.player.store.MediaStore;
import com.cxs.musicplaywidget.player.store.VolumeStore;
import com.cxs.musicplaywidget.util.LogUtils;
import ohos.app.Context;
import ohos.media.common.Source;
import ohos.media.player.Player;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.cxs.musicplaywidget.player.constant.PlayStatus.*;


public class MusicPlayer implements IMusicPlayer {
    private volatile static MusicPlayer musicPlayer = null;
    private int state = STOP_STATE;
    private static Player player;
    private final Context context;
    private IPlayerListener playerListener;
    private static List<MusicInfo> playList;
    private static int playIndex = -1;
    private static int newIndex = 0;
    private static List<Integer> intList;

    public MusicPlayer(Context context) {
        this.context = context;
        MediaStore mediaStore = MediaStore.getInstance(context);
        playList = mediaStore.getMedia();
        if (playList != null) {
            intList = IntStream.rangeClosed(0, getCount())
                    .boxed().collect(Collectors.toList());
        }
        LogUtils.debug(tag, "build().playList=" + playList);
    }

    public static MusicPlayer build(Context context) {
        if (musicPlayer == null) {
            synchronized (MusicPlayer.class) {
                if (musicPlayer == null) {
                    musicPlayer = new MusicPlayer(context);
                }
            }
        }
        return musicPlayer;
    }

    public void setPlayerListener(IPlayerListener playerListener) {
        this.playerListener = playerListener;
    }

    @Override
    public synchronized void start(MusicInfo music) {
        if (music == null) {
            return;
        }
        String filePath = music.getPath();
        if (filePath.equals("") || filePath == null) {
            return;
        }

        if (player != null) {
            // 释放player
            // 必须release()，否则会出现同时播放多个音频的问题
            try {
                player.release();
            } catch (Exception e) {
                LogUtils.debug(tag, "player release failed! " + e.getMessage());
            }
            player = null;
        }

        player = new Player(context);
        try {
            Source source = new Source(filePath);
            player.setSource(source);
            LogUtils.debug(tag, "start.playerListener=" + playerListener);
            player.setPlayerCallback(playerListener);
            player.prepare();
            // 开始播放
            if (player.play()) {
                state = PLAY_STATE;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public synchronized void play() {
        LogUtils.debug(tag, "play.playList=" + playList);
        if (playList == null || playList.size() == 0) {
            return;
        }
        if (state == PAUSE_STATE && newIndex == playIndex) {
            // 如果是暂停状态，并且要播放的歌曲是当前歌曲，则继续播放
            LogUtils.debug(tag, "play.play()");
            player.play();
            state = PLAY_STATE;
        } else {
            // 否则从头开始播放
            LogUtils.debug(tag, "play.start(music)");
            playIndex = newIndex;
            MusicInfo music = getMusic(playIndex);
            start(music);
        }
    }

    @Override
    public synchronized void play(int index) {
        MusicPlayer.newIndex = index;
        play();
    }

    @Override
    public synchronized void pause() {
        if (state != PLAY_STATE) {
            return;
        }
        player.pause();
        state = PAUSE_STATE;
    }

    @Override
    public synchronized void stop() {
        if (state == STOP_STATE) {
            return;
        }
        player.stop();
        state = STOP_STATE;
    }

    @Override
    public void setPlayIndex(int index) {
        playIndex = index;
    }

    @Override
    public int getPlayIndex() {
        return playIndex;
    }

    @Override
    public MusicInfo getMusic() {
        return getMusic(getPlayIndex());
    }

    @Override
    public MusicInfo getMusic(int index) {
        if (playList == null || playList.size() == 0) {
            return null;
        }
        return playList.get(index);
    }

    @Override
    public boolean isPlaying() {
        if (player == null) {
            return false;
        }
        return player.isNowPlaying();
    }

    @Override
    public int getCount() {
        if (playList == null) {
            return 0;
        }
        return playList.size();
    }

    @Override
    public int getCurrentTime() {
        return player.getCurrentTime();
    }

    @Override
    public void updatePlayList() {
        MediaStore mediaStore = MediaStore.getInstance(context);
        MusicPlayer.playList = mediaStore.getMedia();
    }

    @Override
    public List<MusicInfo> getPlayList() {
        return getPlayList(false);
    }

    @Override
    public List<MusicInfo> getPlayList(boolean reload) {
        if (reload || playList == null) {
            MediaStore mediaStore = MediaStore.getInstance(context);
            playList = mediaStore.getMedia(true);
        }
        return playList;
    }

    @Override
    public int getState() {
        return state;
    }

    @Override
    public int next() {
        int newIndex = playIndex + 1;
        if (newIndex >= playList.size()) {
            newIndex = 0;
        }
        return newIndex;
    }

    @Override
    public int previous() {
        int newIndex = playIndex - 1;
        if (newIndex < 0) {
            newIndex = playList.size() - 1;
        }
        return newIndex;
    }

    @Override
    public int random() {
        Random random = new Random();
        int i = random.nextInt(intList.size());
        newIndex = intList.remove(i);
        if (intList.isEmpty()) {
            intList = IntStream.rangeClosed(0, getCount())
                    .boxed().collect(Collectors.toList());
        }
        return newIndex;
    }

    @Override
    public byte[] getThumbnail() {
        MediaStore mediaStore = MediaStore.getInstance(context);
        return mediaStore.getThumbnail(getMusic());
    }

    @Override
    public MusicData getMusicData(int playIndex) {
        MediaStore mediaStore = MediaStore.getInstance(context);
        return mediaStore.getMusicData(getMusic(playIndex));
    }

    @Override
    public int getMaxVolume() {
        VolumeStore volumeStore = VolumeStore.getInstance(context);
        return volumeStore.getMaxVolume();
    }

    @Override
    public int getVolume() {
        VolumeStore volumeStore = VolumeStore.getInstance(context);
        return volumeStore.getVolume();
    }

    @Override
    public void decrease() {
        VolumeStore volumeStore = VolumeStore.getInstance(context);
        int volume = volumeStore.getVolume();
        if (volume == 0) {
            return;
        }
        volumeStore.setCurrentVolume(volume - 1);
    }

    @Override
    public void increase() {
        VolumeStore volumeStore = VolumeStore.getInstance(context);
        int volume = volumeStore.getVolume();
        if (volume == volumeStore.getMaxVolume()) {
            return;
        }
        volumeStore.setCurrentVolume(volume + 1);
    }
}
